package com.sojson.util.idcard.qxb;

import java.io.IOException;

import com.sojson.config.exception.TransErrorCode;
import com.sojson.config.exception.bean.Status;
import com.sojson.util.ExpUtil;
import com.sojson.util.StringUtil;
import com.sojson.util.SystemParamBaseUtil;
import com.sojson.util.encrypt.oneway.alike.md5.Md5Util;
import com.sojson.util.httpclient.HttpClientUtil;
import com.sojson.util.idcard.qxb.bean.QxbConfig;
import com.sojson.util.idcard.qxb.bean.QxbHeader;
import com.sojson.util.idcard.qxb.bean.QxbParam;
import com.sojson.util.idcard.qxb.bean.QxbResponse;
import com.sojson.util.idcard.qxb.bean.child.response.QxbResData;
import com.sojson.util.idcard.qxb.constant.QxbConstant;
import com.sojson.util.idcard.qxb.enums.EQxbApiType;
import com.sojson.util.idcard.qxb.enums.EQxbLocationType;
import com.sojson.util.idcard.qxb.enums.EQxbMatchType;
import com.sojson.util.json.JsonUtil;

/**
 * 启信宝身份证工具类
 * 
 * @author liu
 * @date 2021-07-29
 */
public class IdCardQxbUtil {

    private static IdCardQxbUtil idCardUtil;

    /**
     * 获取企业基本信息(模糊查询)
     * 
     * @param keyword   公司全名或企业注册号
     * @return
     * @throws Exception 
     */
    public QxbResData pageQyBasicInfoByLike(String keyword) throws Exception {
        return pageQyBasicInfoByLike(EQxbMatchType.ENAME, keyword);
    }

    /**
     * 获取企业基本信息(模糊查询)
     * 
     * @param keyword   公司全名或企业注册号
     * @return
     * @throws Exception 
     */
    public QxbResData pageQyBasicInfoByLike(EQxbMatchType matchType, String keyword) throws Exception {
        // 获取配置参数
        QxbConfig config = getConfig();

        // 设置参数
        QxbParam param = new QxbParam();
        param.setMatchType(matchType.getCode());
        param.setKeyword(keyword);

        // 设置请求头
        QxbHeader header = getHeader(config);

        // 发送请求
        String doGetByParam =
            HttpClientUtil.doGet(EQxbApiType.BASIC_INFO_LIKE.getType(), objectToJson(header), objectToJson(param));
        // 获取结果
        QxbResponse jsonToObject = jsonToObject(doGetByParam, header, config);
        Status cusStatus = jsonToObject.getCusStatus();
        // 如果请求失败就抛异常
        if (cusStatus.isFail()) {
            ExpUtil.throwEx(cusStatus.getMsg());
        }

        return jsonToObject.getData();
    }

    /**
     * 获取企业基本信息
     * 
     * @param keyword   公司全名或企业注册号
     * @return
     * @throws Exception 
     */
    public QxbResData getQyBasicInfo(String keyword) throws Exception {
        // 获取配置参数
        QxbConfig config = getConfig();

        // 设置参数
        QxbParam param = new QxbParam();
        param.setKeyword(keyword);

        // 设置请求头
        QxbHeader header = getHeader(config);

        // 发送请求
        String doGetByParam =
            HttpClientUtil.doGet(EQxbApiType.BASIC_INFO.getType(), objectToJson(header), objectToJson(param));
        // 获取结果
        QxbResponse jsonToObject = jsonToObject(doGetByParam, header, config);
        Status cusStatus = jsonToObject.getCusStatus();
        // 如果请求失败就抛异常
        if (cusStatus.isFail()) {
            ExpUtil.throwEx(cusStatus.getMsg());
        }

        return jsonToObject.getData();
    }

    /**
     * 获取企业联系方式
     * 
     * @param keyword   公司全名或企业注册号
     * @return
     * @throws Exception 
     */
    public QxbResData getQyContactInfo(String keyword) throws Exception {
        // 获取配置参数
        QxbConfig config = getConfig();

        // 设置参数
        QxbParam param = new QxbParam();
        param.setKeyword(keyword);

        // 设置请求头
        QxbHeader header = getHeader(config);

        // 发送请求
        String doGetByParam =
            HttpClientUtil.doGet(EQxbApiType.CONTACT_INFO.getType(), objectToJson(header), objectToJson(param));
        // 获取结果
        QxbResponse jsonToObject = jsonToObject(doGetByParam, header, config);
        Status cusStatus = jsonToObject.getCusStatus();
        // 如果请求失败就抛异常
        if (cusStatus.isFail()) {
            ExpUtil.throwEx(cusStatus.getMsg());
        }

        return jsonToObject.getData();
    }

    /**
     * 获取企业坐标
     * 
     * @param keyword   公司全名或企业注册号
     * @return
     * @throws Exception 
     */
    public QxbResData getQyLocation(String keyword) throws Exception {
        return getQyLocation(EQxbLocationType.BD, keyword);
    }

    /**
     * 获取企业坐标
     * 
     * @param locationType  坐标类型
     * @param name          公司全名或企业注册号
     * @return
     * @throws Exception 
     */
    public QxbResData getQyLocation(EQxbLocationType locationType, String name) throws Exception {
        // 获取配置参数
        QxbConfig config = getConfig();

        // 设置参数
        QxbParam param = new QxbParam();
        param.setName(name);
        param.setType(locationType.getCode());

        // 设置请求头
        QxbHeader header = getHeader(config);

        // 发送请求
        String doGetByParam =
            HttpClientUtil.doGet(EQxbApiType.QY_LOCATION.getType(), objectToJson(header), objectToJson(param));
        // 获取结果
        QxbResponse jsonToObject = jsonToObject(doGetByParam, header, config);
        Status cusStatus = jsonToObject.getCusStatus();
        // 如果请求失败就抛异常
        if (cusStatus.isFail()) {
            ExpUtil.throwEx(cusStatus.getMsg());
        }

        return jsonToObject.getData();
    }

    /**
     * 获取Appkey
     * 
     * @return
     * @throws IOException 
     */
    private String getAppkey() throws IOException {
        return get(QxbConstant.APPKEY);
    }

    /**
     * 获取SecretKey
     * 
     * @return
     * @throws IOException 
     */
    private String getSecretKey() throws IOException {
        return get(QxbConstant.SECRET_KEY);
    }

    /**
     * 获取启信宝配置参数
     * 
     * @return
     * @throws IOException 
     */
    private QxbConfig getConfig() throws IOException {
        QxbConfig config = new QxbConfig();
        config.setAppkey(getAppkey());
        config.setSecretKey(getSecretKey());
        return config;
    }

    /**
     * 获取启信宝请求头
     * 
     * @return
     * @throws IOException 
     */
    private QxbHeader getHeader(QxbConfig config) throws IOException {
        QxbHeader header = new QxbHeader();
        header.setAuthVersion(QxbConstant.AUTH_VERSION);
        header.setAppkey(config.getAppkey());
        header.setTimestamp(System.currentTimeMillis() + "");
        setSign(header, config);
        return header;
    }

    /**
     * 设置签名
     * 
     * @return
     * @throws IOException 
     */
    private void setSign(QxbHeader header, QxbConfig config) throws IOException {
        String sign = getSign(header.getAppkey(), config.getSecretKey(), header.getTimestamp());
        header.setSign(sign);
    }

    /**
     * 获取签名
     * 
     * @param appkey
     * @param secretKey
     * @param timestamp 当前时间戳(单位: 毫秒)
     * @return
     * @throws IOException 
     */
    private String getSign(String appkey, String secretKey, String timestamp) throws IOException {
        return Md5Util.encrypt(appkey + timestamp + secretKey).toLowerCase();
    }

    /**
     * 判断一个对象是否是空(空对象)
     * 
     * @param obj
     * @return
     */
    private static boolean isBlankObject(Object obj) {
        return StringUtil.isBlankObject(obj);
    }

    /**
     * 将对象转换成json字符串(值为空的不解析)
     * 
     * @param data 被转换的对象
     * @return 得到的字符串
     */
    private String objectToJson(Object data) throws IOException {
        return JsonUtil.objectToJson(data);
    }

    /**
     * 将json字符串转换成对象
     * 
     * @param jsonData  json字符串
     * @param header    请求头
     * @param config    请求参数
     * @return
     * @throws IOException 
     */
    private QxbResponse jsonToObject(String jsonData, QxbHeader header, QxbConfig config) throws IOException {
        // 将Json转为对象
        QxbResponse jsonToObject = JsonUtil.jsonToObject(jsonData, QxbResponse.class);

        Status status = new Status();
        jsonToObject.setCusStatus(status);

        // 获取状态码
        String statusResult = jsonToObject.getStatus();
        // 如果请求失败就结束
        if (!QxbConstant.SUCCESS.equals(statusResult) && !QxbConstant.NO_RESULT.equals(statusResult)) {
            status.setCode(TransErrorCode.FAIL.getCode());
            status.setMsg(jsonToObject.getMessage());
            return jsonToObject;
        }

        // // 获取签名
        // String sign = jsonToObject.getSign();
        // // 如果签名不存在就结束
        // if (isBlankObject(sign)) {
        // status.setCode(TransErrorCode.FAIL.getCode());
        // status.setMsg("签名不存在");
        // return jsonToObject;
        // }
        //
        // // 如果签名错误就结束
        // if (!getSign(param.getAppkey(), param.getSecretKey(), header.getTimestamp()).equals(sign)) {
        // status.setCode(TransErrorCode.FAIL.getCode());
        // status.setMsg("签名错误");
        // return jsonToObject;
        // }

        // 返回成功
        status.setCode(TransErrorCode.SUCCESS.getCode());
        return jsonToObject;
    }

    /**
     * 从缓存中获取值
     * 
     * @param key
     * @return
     * @throws IOException
     */
    private String get(String key) throws IOException {
        return SystemParamBaseUtil.getStr(key);
    }

    public static IdCardQxbUtil getInstances() {
        if (isBlankObject(idCardUtil)) {
            idCardUtil = new IdCardQxbUtil();
        }
        return idCardUtil;
    }

}